package com.efun.center.http.config;

import java.util.Set;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.StringUtils;

import com.efun.center.http.annotation.HttpService;

public class ServiceScanner extends ClassPathBeanDefinitionScanner {

	/**
	 * 服务接口实现类
	 */
	protected Class<?> serviceFactoryBeanClass;

	public ServiceScanner(BeanDefinitionRegistry registry) {
		super(registry, false);
	}

	public void setServiceFactoryBeanClass(Class<?> serviceFactoryBeanClass) {
		this.serviceFactoryBeanClass = serviceFactoryBeanClass;
	}

	/**
	 * 初始化
	 */
	public void init() {
		addIncludeFilter(new AnnotationTypeFilter(HttpService.class));

		if (serviceFactoryBeanClass == null) {
			serviceFactoryBeanClass = ServiceFactoryBean.class;
		}
	}

	/**
	 * 扫描
	 */
	public int scan() {
		return scan(StringUtils.tokenizeToStringArray("com.efun.center", ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
	}

	/**
	 * 扫描
	 */
    @Override
	public Set<BeanDefinitionHolder> doScan(String... basePackages) {
		// 获取扫描结果
		Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);

        GenericBeanDefinition definition;
        for (BeanDefinitionHolder holder : beanDefinitions) {
            definition = (GenericBeanDefinition) holder.getBeanDefinition();

            definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName());

            // 设置Bean的实现类
            definition.setBeanClass(serviceFactoryBeanClass);

            definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }

		return beanDefinitions;
	}

	@Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();
    }

}
